package token

import (
	"encoding/json"
	"time"

	"gitee.com/go-kade/go12/vblog/apps/user"
	"gitee.com/go-kade/go12/vblog/exception"
	"github.com/rs/xid"
)

type Token struct {
	UserID                int64  `json:"user_id" gorm:"column:user_id"`                                   //该token是颁发给谁的
	UserName              string `json:"username" gorm:"column:username"`                                 //人的名字
	AccessToken           string `json:"access_token" gorm:"column:access_token"`                         //颁发给用户的访问令牌（需要用户携带token来访问接口）
	AccessTokenExpiredAt  int    `json:"access_token_expired_at" gorm:"column:access_token_expired_at"`   //过期时间
	RefreshToken          string `json:"refresh_token" gorm:"column:refresh_token"`                       //刷新令牌
	RefreshTokenExpiredAt int    `json:"refresh_token_expired_at" gorm:"column:refresh_token_expired_at"` //刷新令牌过期时间
	CreatedAt             int64  `json:"created_at" gorm:"column:created_at"`                             //创建时间
	UpdatedAt             int64  `json:"updated_at" gorm:"column:updated_at"`                             //刷新时间
	// AccessTokens          string `json:"access_tokens"`                   //颁发给用户的访问令牌（需要用户携带token来访问接口）
	Role user.Role `gorm:"-"` // 额外补充信息, gorm忽略处理,这样就不需要存在数据库中了
}

func NewToken() *Token {
	return &Token{
		AccessToken:           xid.New().String(),
		AccessTokenExpiredAt:  7200,
		RefreshToken:          xid.New().String(),
		RefreshTokenExpiredAt: 3600 * 24 * 7,
		CreatedAt:             time.Now().Unix(),
		UpdatedAt:             time.Now().Unix(),
		// AccessTokens:          xid.New().String(),
	}
}

func (t *Token) TableName() string {
	return "tokens"
}

func (t *Token) String() string {
	dj, _ := json.Marshal(t)
	return string(dj)
}

func (t *Token) IsExpired() error {
	duration := time.Since(t.ExpiredTime())
	expiredSeconds := duration.Seconds()
	if expiredSeconds > 0 {
		return exception.NewNotFound("token %s 过期了 %f秒", t.AccessToken, duration.Seconds())
	}
	return nil
}

// 计算token的过期时间
func (t *Token) ExpiredTime() time.Time {
	return time.Unix(t.CreatedAt, 0).Add(time.Duration(t.AccessTokenExpiredAt) * time.Second)
	//time.Unix(t.CreatedAt, 0)它接受两个参数，第一个参数是秒数，第二个参数是纳秒数。
	//time.Duration(t.AccessTokenExpiredAt) * time.Second 将整数值转换为 Go 的时间s。
}
